﻿/*----------------------------------------------------------------
//  <copyright file="BasicAuthAuthorizationUser.cs" company="MicroCloud@151504200868">
//      Copyright © 2020-2024 MicroCloud Corporation, All rights reserved.
//  </copyright>
//  <site>https://gitee.com/chenmm123/microclouds</site>
//  <last-editor>cmm</last-editor>
//  <last-date>2024-03-04 14:50</last-date>
//----------------------------------------------------------------*/

namespace MicroCloud.Hangfire.Dashboard.Authorization
{
    #region "表示通过基本身份验证访问Hangfire仪表板的用户"
    /// <summary>
    /// 表示通过基本身份验证访问Hangfire仪表板的用户
    /// （Represents user to access Hangfire dashboard via basic authentication）
    /// </summary>
    public class BasicAuthAuthorizationUser
    {
        #region "属性"
        #region "获取 设置或验证密码时用于密码哈希计算的回调"
        /// <summary>
        /// 获取 设置或验证密码时用于密码哈希计算的回调
        /// </summary>
        public Func<HashAlgorithm> CryptoProviderFactory { get; private set; }
        #endregion
        #region "获取或设置 登录名"
        /// <summary>
        /// 获取或设置 登录名
        /// </summary>
        public string UserId { get; set; }
        #endregion
        #region "获取或设置 登录密码"
        private string _Password = string.Empty;
        /// <summary>
        /// 获取或设置 登录密码，
        /// 通过使用给定的<see cref="CryptoProviderFactory"/>自动对字符串进行散列，设置字符串的<see cref="PasswordHash"/>属性。
        /// </summary>
        public string Password
        {
            get { return _Password; }
            set
            {
                _Password = value;
                using var cryptoProvider = CryptoProviderFactory();
                PasswordHash = cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(_Password));
            }
        }
        #endregion
        #region "获取或设置 用户的密码哈希"
        /// <summary>
        /// 获取或设置 用户的密码哈希。请使用<see cref="Password"/>属性设置将自动散列的纯文本密码。
        /// </summary>
        public byte[] PasswordHash { get; set; }
        #endregion

        #endregion

        #region "构造函数"
        #region "初始化一个通过基本身份验证访问Hangfire仪表板的用户的新实例"
        /// <summary>
        /// 初始化一个通过基本身份验证访问Hangfire仪表板的用户 <see cref="BasicAuthAuthorizationUser"/> 的新实例。
        /// <see cref="SHA1"/> 作为加密提供者。
        /// </summary>
        public BasicAuthAuthorizationUser()
            : this(SHA1.Create)
        {
        }
        #endregion
        #region "初始化一个通过基本身份验证访问Hangfire仪表板的用户的新实例"
        /// <summary>
        /// 初始化一个通过基本身份验证访问Hangfire仪表板的用户 <see cref="BasicAuthAuthorizationUser"/> 的新实例。
        /// 指定的 <paramref name="cryptoProviderFactory"/> 将用作加密提供程序。
        /// </summary>
        public BasicAuthAuthorizationUser(Func<HashAlgorithm> cryptoProviderFactory)
        {
            CryptoProviderFactory = cryptoProviderFactory ?? throw new ArgumentNullException(nameof(cryptoProviderFactory));
        }
        #endregion

        #endregion

        #region "方法"
        #region "验证用户"
        /// <summary>
        /// 验证用户
        /// </summary>
        /// <param name="userId">用户名</param>
        /// <param name="password">用户密码</param>
        /// <param name="loginCaseSensitive">登录检查是否区分大小写</param>
        /// <returns></returns>
        public bool Validate(string userId, string password, bool loginCaseSensitive = false)
        {
            if (string.IsNullOrWhiteSpace(userId) == true)
            {
                throw new ArgumentNullException(nameof(userId));
            }
            if (string.IsNullOrWhiteSpace(password) == true)
            {
                throw new ArgumentNullException(nameof(password));
            }
            if (userId.Equals(UserId, loginCaseSensitive ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase) == true)
            {
                using var cryptoProvider = CryptoProviderFactory();
                byte[] passwordHash = cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(password));
                return StructuralComparisons.StructuralEqualityComparer.Equals(passwordHash, PasswordHash);
            }
            else
            {
                return false;
            }
        }
        #endregion

        #endregion

    }
    #endregion

}
